package com.intel.factorytest.activity;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.intel.factorytest.R;
import com.intel.factorytest.application.MATApplication;
import com.intel.factorytest.cfparser.ConfigFileParseUtil;
import com.intel.factorytest.cfparser.concrete.AConfigFileParser;
import com.intel.factorytest.cfparser.concrete.PropertiesConfParser;
import com.intel.factorytest.log.LogWriter;
import com.intel.factorytest.util.LogUtils;

public  class BluetoothTest extends BaseActivity {
    private static final String TAG = "BluetoothTest";
//    private static final int MAX_COUNT_DEV_DISPLAY = 5;
    private static final int MAX_COUNT_DEV_DISPLAY = 3;
    private static final int BT_NODEFINE_BASE_LINE = 70;

    // Handler Message
    private static final int MSG_CHECK_RESULT = 1;

    // Timer
    private Timer mTimer_CheckResult = null;

    // properties
    private Properties properties;

    // test result
    private boolean resultBTOK = false;
    private boolean mCanScanBT = false;

    private static final String KEY_BT_SSID = "BT_SSID";
    private static final String KEY_BT_RSSI = "BT_RSSI";
    private static final String KEY_BT_RSSI_ERROR_LIMITATION = "BT_RSSI_ERROR_LIMITATION";


    private String valueBTSsid;
    private String valueBTRssi;
    private int valueBTRssiErrorLimitation = 10;
    private String[] ssidsBT;
    private String[] rssisBT;


    private boolean isCheckedBT = false;

    //  ######  Bluetooth  #########
    private BluetoothAdapter mAdapter_BT = null;
    private static final int SET_BT_STATUS = 1;
    private static final int RESTORE_BT_STATUS = 2;
    private Timer mTimer_BT;
    private IntentFilter mFilter_BT = null;
    private BroadcastReceiver mReceiver_BT;
    private TextView btLabelText = null;
    private TextView btDevInfosTv = null;
    private long mLastScan;
    private int mdeviceCount_BT = 0;
    private String mBTDevicesInfo = "";
    private static final int SCAN_EXPIRATION_MS = 10 * 1000;
    private int mBtState = 0;
    Handler mHandler_BT = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == SET_BT_STATUS){
                if(BluetoothAdapter.STATE_ON != mAdapter_BT.getState()) {
                    mAdapter_BT.enable();
                } else {
                    startScanning(true);
                }
            } else if(msg.what == RESTORE_BT_STATUS) {
                if((BluetoothAdapter.STATE_ON == mAdapter_BT.getState()) && (mBtState != BluetoothAdapter.STATE_ON)) {
                    mAdapter_BT.disable();
                }
            } else {
            }

        }
    };



    boolean isExistAll_bt = false;
//    boolean isSsidBeyondLimit_bt = false;
    boolean isBTSsidTestOK = false;



    protected void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // load properties configuration file
        properties = ((PropertiesConfParser) ConfigFileParseUtil.getConfParserConcrete(this, AConfigFileParser.EXTENSION_PROPERTISE)).getProperties(isPcba);
         valueBTSsid = properties.getProperty(KEY_BT_SSID);
         valueBTRssi = properties.getProperty(KEY_BT_RSSI);
         Log.i("TAG", "valueBTSsid = " + valueBTSsid+"valueBTRssi:"+valueBTRssi);
         valueBTRssiErrorLimitation = Integer.parseInt(properties.getProperty(KEY_BT_RSSI_ERROR_LIMITATION));
         ssidsBT = valueBTSsid.split(";");
         rssisBT = valueBTRssi.split(";");
        
        setContentView(R.layout.bluetooth_test_layout);
        initView();


        mFilter_BT = new IntentFilter();
        mFilter_BT.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        mFilter_BT.addAction(BluetoothDevice.ACTION_FOUND);
        mFilter_BT.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        //mFilter_BT.addAction(BluetoothDevice.ACTION_DISAPPEARED);
        mFilter_BT.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        mReceiver_BT = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!isCheckedBT) {
                    handleBluetoothEvent(context, intent);
                }
            }
        };

        mAdapter_BT = BluetoothAdapter.getDefaultAdapter();
        mBtState = mAdapter_BT.getState();
    }

    protected void initView() {


        btLabelText = (TextView) findViewById(R.id.btTextView);
        btLabelText.setText(this.getString(R.string.BT_TITLE));

        btDevInfosTv = (TextView) findViewById(R.id.btDevInfos);
        btDevInfosTv.setText(this.getString(R.string.SERVICEMENU_BT_OPEN_TXT));

        mSucBtn = (Button) findViewById(R.id.success_button);

        if(!isBTTestOK())//if (isSystemTest)
        {
            mSucBtn.setVisibility(View.INVISIBLE);
        }
        
        mFailBtn = (Button) findViewById(R.id.fail_button);

        attachListener();
    }

    private void attachListener() {
        mSucBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                is_pass = true;
                finish();
            }
        });
        attachOnTouchListener(mSucBtn);

        mFailBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                is_pass = false;
                finish();
            }
        });
        attachOnTouchListener(mFailBtn);
    }
    
    private Handler mHandler_CheckResult = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            // update is_pass
            if (isBTTestOK()) {
                is_pass = true;
            } else {
                is_pass = false;
            }

            switch (msg.what) {
            case MSG_CHECK_RESULT:
                if (is_pass) {
                    mSucBtn.setVisibility(View.VISIBLE);
                    //finish();
                } else {
                    if (mCanScanBT){
                        is_pass = true;
                        mSucBtn.setVisibility(View.VISIBLE);
                        //finish();
                    }
                    else
                    {
                    }
                    mFailBtn.setVisibility(View.VISIBLE);
                    mFailBtn.setEnabled(true);
                }
                break;
            default:
                break;
            }

        }

    };



/**
* 检查SSID and RSSI的数量是否一致
* @return
*/

   private boolean checkBTFormat() {
         if (valueBTSsid == null || valueBTSsid.trim().length() == 0 || valueBTRssi == null || valueBTRssi.trim().length() == 0) {
            return false;
        }
        if (ssidsBT.length != rssisBT.length) {
          return false;
        }
        return true;
     }

     private void startCheck() {

        mTimer_CheckResult = new Timer();
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                if (isSystemTest) {
                    mHandler_CheckResult.sendEmptyMessage(MSG_CHECK_RESULT);
                }
            }
        };
        mTimer_CheckResult.schedule(task, 500, 500);
        
     }
    

    
    List<String> scanedSsid = new ArrayList<String>();
    private boolean isScaned(String ssid) {
        return scanedSsid.contains(ssid);
    }

    private void handleBluetoothEvent(Context context, Intent intent) {
        if (!checkAllBTSsidExist()) {
            isExistAll_bt = false;
        } else {
            isExistAll_bt = true;
        }
        
        String action = intent.getAction();
        Log.i("TAG", "action = " + action);
        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                updateBlueToothState(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR));
            Log.i("TAG", "updateBlueToothState");

        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
        } else if(BluetoothDevice.ACTION_FOUND.equals(action)) {
            mdeviceCount_BT++;
            updateBTInfoSet(intent);
//            mBTDevicesInfo +=  "\n" + getBTDevInfo(intent); // this.getString(R.string.SERVICEMENU_BT_SCAN_RESULT_TXT) + mdeviceCount_BT;
//            tmpStr +=  "\n" + this.getString(R.string.SERVICEMENU_BT_TEST_RESULT_TXT);
            btDevInfosTv.setText(buildAllBTInfo());
            Log.i("TAG", "results.size() = " + mdeviceCount_BT);

        } /*else if(BluetoothDevice.ACTION_DISAPPEARED.equals(action)) {
            if(mdeviceCount_BT > 0) {
                mdeviceCount_BT--;
                updateBTInfoSet(intent);
            }
//            String tmpStr = this.getString(R.string.SERVICEMENU_BT_OPEN_TXT) + "\n" + this.getString(R.string.SERVICEMENU_BT_SCAN_RESULT_TXT) + mdeviceCount_BT;
//            tmpStr +=  "\n" + this.getString(R.string.SERVICEMENU_BT_TEST_RESULT_TXT); \
//            mBTDevicesInfo =  "\n" + getBTDevInfo(intent);
            btDevInfosTv.setText(buildAllBTInfo());
            Log.i("TAG", "results.size() = " + mdeviceCount_BT);

        }
        */
        if (isExistAll_bt && isBTSsidTestOK) {
            resultBTOK = true;
        } else {
            resultBTOK = false;
        }
    }

    class BTInfo {
        String name;
        String address;
        short rssi;

        BTInfo(String name, String address, short rssi) {
            this.name = name;
            this.address = address;
            this.rssi = rssi;
        }

        @Override
        public int hashCode() {
            return address.hashCode();
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof BTInfo) {
                BTInfo other = (BTInfo) o;
                if (other.address.equals(address)) {
                    return true;
                } else {
                    return false;
                }
            }
            return false;
        }
    }

    private Set<BTInfo> mBTInfoSet = new HashSet<BTInfo>();
    private void updateBTInfoSet(Intent intent) {
        String btName = null;
        String btAddr = null;
        short btRssi = 0;
        String action = intent.getAction();
        // 从Intent得到blueDevice对象
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (device == null) {
            return;
        }
        // 设备名称
        btName = device.getName();
        // 设备地址
        btAddr = device.getAddress();
        // 信号强度。
        btRssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
        // 当设备开始扫描时。
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                mBTInfoSet.add(new BTInfo(btName, btAddr, btRssi));
            }
        } /*else if (BluetoothDevice.ACTION_DISAPPEARED.equals(action)) {
            if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                mBTInfoSet.remove(new BTInfo(btName, btAddr, btRssi));
            }
        }*/

        if (mBTInfoSet.size()!=0)
        {
            mCanScanBT=true;
        }
    }

    private boolean checkAllBTSsidExist() {
        if (ssidsBT != null && ssidsBT.length == 1 && ssidsBT[0].trim().length() == 0) {
            return true;
        }
        for (String ssid : ssidsBT) {
            System.out.println("tangjun bt ssid=" + ssid);
            boolean isExist = false;
            for (BTInfo info : mBTInfoSet) {
                if (ssid.equals(info.name)) {
                    isExist = true;
                }
            }
            if (!isExist) {
                return false;
            }
        }
        return true;
    }

    protected boolean CheckRSSIResult(int baseline, int actual) {
         return Math.abs(baseline)>Math.abs(actual)?true:false;
     }

    private String buildAllBTInfo() {
        StringBuilder builder = new StringBuilder();
        int btCount = 0;

//        return builder.toString();
        for (int i = 0; i < ssidsBT.length; i++) {
            for (BTInfo btInfo : mBTInfoSet) {
                try {
                    if (ssidsBT[i].equals(btInfo.name)) {
                        builder.append(getString(R.string.SSID)).append(btInfo.name).append(getString(R.string.RSSI)).append(btInfo.rssi).append("dbm");
                        if (isSystemTest) {
                            int baseline = Integer.parseInt(rssisBT[i]);
                            int actual = btInfo.rssi;
//                            if (!checkErrorResult(expect, actual, valueBTRssiErrorLimitation)) {
                            if (!CheckRSSIResult(baseline, actual)) {
                                builder.append(getString(R.string.RSSIFail));
                                isBTSsidTestOK = false;
                            } else {
                                builder.append(getString(R.string.RSSIPass));
                                isBTSsidTestOK = true;
                            }
                        }
                        Log.i("TAG", "btInfo.name = " + btInfo.name+"btInfo.rssi:"+btInfo.rssi);
                        builder.append("\n");
                        btCount++;
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    continue;
                }
            }
        }
        Iterator<BTInfo> it = mBTInfoSet.iterator();
        while (it.hasNext()) {
            if (btCount >= MAX_COUNT_DEV_DISPLAY) {
                break;
            }
            try {
                BTInfo btInfo = it.next();
                boolean isExist = false;
                for (String ssid : ssidsBT) {
                    if (btInfo.name.equals(ssid)) {
                        isExist = true;
                    }
                }
                if (!isExist) {
                    btCount++;
                    Log.i("TAG", "btInfo.name = " + btInfo.name+"btInfo.rssi:"+btInfo.rssi);
                    builder.append(getString(R.string.SSID)).append(btInfo.name).append(getString(R.string.RSSI)).append(btInfo.rssi).append("dbm");
//                    if (CheckRSSIResult(BT_NODEFINE_BASE_LINE, btInfo.rssi))
//                    {
//                        builder.append(getString(R.string.RSSIPass));
//                        isBTSsidTestOK = true;
//                    }

                    builder.append("\n");
                }
            } catch (Exception e) {
                // TODO: handle exception
                continue;
            }
        }
        return builder.toString();
    }

    private void updateBlueToothState(int state) {
        switch (state) {
            case BluetoothAdapter.STATE_ON:
            btLabelText.setText(this.getString(R.string.SERVICEMENU_BT_OPEN_TXT));
            startScanning(false);
            return; 
            case BluetoothAdapter.STATE_OFF:
            btLabelText.setText(this.getString(R.string.SERVICEMENU_BT_TEST_RESULT_FAIL_TXT));
            break;
        }
    }

    void startScanning(boolean force) {
        if (!mAdapter_BT.isDiscovering()) {
            if (!force) {
            // Don't scan more than frequently than SCAN_EXPIRATION_MS,
            // unless forced
            if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
                return;
            }
            }

            if (mAdapter_BT.startDiscovery()) {
            mLastScan = System.currentTimeMillis();
            }
        }
    }



    @Override
    protected void onResume() {
        super.onResume();
        //registerReceiver(mReceiver_BT, mFilter_BT, "permission.CIT_ALLOW_BROADCAST", null);
        registerReceiver(mReceiver_BT, mFilter_BT);
        mTimer_BT = new Timer();
        mTimer_BT.schedule(new TimerTask(){
            @Override
            public void run() {
                mHandler_BT.sendEmptyMessage(SET_BT_STATUS);
            }

        }, 1000);
        
        // check result
        startCheck();
        mItemTestFinish = true;//add by wangsm
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver_BT);
        if (mTimer_CheckResult != null) {
            mTimer_CheckResult.cancel();
        }
    }

    @Override
    public void onDestroy() {
        restoreBTThread();
        super.onDestroy();
    }

    @Override
    public void finish() {
        isLogged = true;
        scanedSsid.clear();
        super.finish();
    }



    private boolean isBTTestOK() {
        return resultBTOK;
    }


    Runnable runnable = new Runnable() {

        public void run() {
            mHandler_BT.sendEmptyMessage(RESTORE_BT_STATUS);
        };
    };

    private void restoreBTThread() {
       new Thread(runnable).start();
    }
}
